﻿using LeRenard.Libraries.Templating.Templating.Mapping;
using System;
using System.Collections.Generic;
using System.Linq;

namespace LeRenard.Libraries.Templating.Templating
{
    /// <summary>
    /// Abstract implementation of <see cref="ITemplate"/>,
    /// which defines a template.
    /// </summary>
    public abstract class TemplateBase : ITemplate
    {
        /// <summary>
        /// Constructs a new <see cref="TemplateBase"/> instance.
        /// </summary>
        /// <param name="templateString"></param>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="templateString"/> is null or empty.</exception>
        public TemplateBase(string templateString)
        {
            ThrowIf.NullOrEmpty(() => templateString);

            _templateString = templateString;
            _templateMappings = new List<ITemplateMapping>();
        }

        /// <summary>
        /// Gets the raw template string, containing the placeholders.
        /// </summary>
        public string TemplateString { get { return _templateString; } }
        private readonly string _templateString;

        /// <summary>
        /// Gets all mappings defined for this template.
        /// </summary>
        public IEnumerable<ITemplateMapping> TemplateMappings { get { return _templateMappings; } }
        private readonly List<ITemplateMapping> _templateMappings;

        /// <summary>
        /// Adds a <see cref="ITemplateMapping"/> to the <see cref="ITemplate"/>.
        /// </summary>
        /// <param name="templateMapping">The template to be added.</param>
        public void AddMapping(ITemplateMapping templateMapping)
        {
            ThrowIf.Null(() => templateMapping);
            if (_templateMappings.Select(m => m.Placeholder).Contains(templateMapping.Placeholder))
                throw new ArgumentException(String.Format("There is already a mapping present for placeholder '{0}'", templateMapping.Placeholder), "templateMapping");

            _templateMappings.Add(templateMapping);
        }
    }
}
